package com.txzt.gaea.contract.service.impl;

import com.txzt.base.constant.RtnConstant;
import com.txzt.base.core.RtnInfo;
import com.txzt.gaea.api.client.AdminUserRemoteService;
import com.txzt.gaea.business.project.domain.model.ProjectContract;
import com.txzt.gaea.business.sequence.service.ISequenceService;
import com.txzt.gaea.common.base.service.impl.BaseServiceImpl;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.enums.BizContractStatusEnum;
import com.txzt.gaea.common.enums.IsDeleteEnum;
import com.txzt.gaea.common.page.PageInfoBT;
import com.txzt.gaea.contract.dto.BizContractDTO;
import com.txzt.gaea.contract.model.BizContract;
import com.txzt.gaea.contract.model.BizContractPayment;
import com.txzt.gaea.contract.service.BizContractService;
import com.txzt.gaea.contract.vo.BizContractVo;
import com.txzt.gaea.dto.UserSingleDetailQueryDTO;
import com.txzt.gaea.provide.service.biz.DeptApiService;
import com.txzt.gaea.vo.ZTreeNodeVO;
import lombok.extern.log4j.Log4j2;
import org.beetl.sql.core.engine.PageQuery;
import org.beetl.sql.core.query.LambdaQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Log4j2
@Service
public class BizContractServiceImpl extends BaseServiceImpl<BizContract> implements BizContractService {

    @Autowired
    private AdminUserRemoteService adminUserRemoteService;
    @Autowired
    private DeptApiService deptApiService;
    @Autowired
    private ISequenceService sequenceService;

    @Override
    public Map<String,Object> statisticsBizContract() {
        List<ZTreeNodeVO> deptList = deptApiService.deptInfoList();
        Long total = sqlManager.allCount(BizContract.class);

        List<Map> mapType =sqlManager.select("bizContract.statisticsType",Map.class,null);

        List<Map> mapList = sqlManager.select("bizContract.statisticsBizContract",Map.class,null);

        mapList.forEach(item->{
            String deptName = null;
            for (ZTreeNodeVO z : deptList) {
                if (Long.parseLong(z.getId()) == (Long)item.get("deptId")){
                    deptName = z.getName();
                    break;
                }
            }
            item.put("deptName",deptName);
        });
        Map<String,Object> map = new HashMap<>();
        map.put("total",total);
        map.put("mapType",mapType);
        map.put("mapList",mapList);
        return map;
    }

    @Override
    public Map<String,Object> getTotalNum(){
        Map<String,Object> map = new HashMap<>();
        LambdaQuery<BizContract> query = sqlManager.lambdaQuery(BizContract.class);
        map.put("total",query.andEq(BizContract::getIsDelete,IsDeleteEnum.NOTDELETE.getCode()).count());
        query = sqlManager.lambdaQuery(BizContract.class);
        map.put("beingTotal",query.andEq(BizContract::getIsDelete,IsDeleteEnum.NOTDELETE.getCode())
                .andEq(BizContract::getStatus,BizContractStatusEnum.BEING.getCode()).count());
        query = sqlManager.lambdaQuery(BizContract.class);
        map.put("finishTotal",query.andEq(BizContract::getIsDelete,IsDeleteEnum.NOTDELETE.getCode())
                .andEq(BizContract::getStatus,BizContractStatusEnum.FINISH.getCode()).count());
        return map;
    }

    @Override
    public RtnInfo<PageInfoBT<BizContractVo>> pageList(BizContractDTO bizContractDTO){
        List<ZTreeNodeVO> deptList = deptApiService.deptInfoList();
        PageQuery<BizContractVo> pageQuery = new PageQuery<>(bizContractDTO.getOffset(),
                bizContractDTO.getLimit(), bizContractDTO);
        PageQuery<BizContractVo> result =
                this.sqlManager.pageQuery("bizContract.selectPageList", BizContractVo.class, pageQuery);
        //为空直接返回
        if (CollectionUtils.isEmpty(result.getList())) {
            return RtnInfo.success(new PageInfoBT<>(result));
        }
        result.getList().forEach(item -> {
            UserSingleDetailQueryDTO userSingleDetailQueryDTO = new UserSingleDetailQueryDTO();
            userSingleDetailQueryDTO.setUserId(item.getCreateBy());
            item.setCreateName(adminUserRemoteService.singleDetailQuery(userSingleDetailQueryDTO).getData().getName());
            userSingleDetailQueryDTO.setUserId(item.getUpdateBy());
            item.setUpdateName(adminUserRemoteService.singleDetailQuery(userSingleDetailQueryDTO).getData().getName());
            String deptName = null;
            for (ZTreeNodeVO z : deptList) {
                if (Long.parseLong(z.getId()) == item.getDeptId()){
                    deptName = z.getName();
                    break;
                }
            }
            item.setDeptName(deptName);
        });
        PageInfoBT<BizContractVo> re = new PageInfoBT<>(result);
        rebuild(re);
        return RtnInfo.success(re);
    }

    private void rebuild(PageInfoBT<BizContractVo> re){
        List<BizContractVo> list = re.getRows();
        if(CollectionUtils.isEmpty(list)){
            re.setTotal(0);
            return;
        }
//        re.setTotal(list.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(BizContract bizContract){
        // 获取当前年
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        Integer sequence = sequenceService.getSequence("biz_contract", "contract_no");
        String contractNo = year + "-HTLR-" + String.format("%03d", sequence);
        bizContract.setContractNo(contractNo);
        bizContract.setStatus(BizContractStatusEnum.BEING.getCode());
        bizContract.setCreateBy(AdminUserContext.getUser().getId());
        bizContract.setCreateTime(new Date());
        bizContract.setUpdateBy(AdminUserContext.getUser().getId());
        bizContract.setUpdateTime(new Date());
        bizContract.setIsDelete(IsDeleteEnum.NOTDELETE.getCode());
        int num = this.sqlManager.insert(bizContract,true);
        if (null == bizContract.getId()){
            return 0;
        }
        if (0 < bizContract.getPaymentList().size()) {
            for (BizContractPayment payment : bizContract.getPaymentList()) {
                payment.setBizId(bizContract.getId());
                this.sqlManager.insert(payment);
            }
        }
        return num;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(BizContract bizContract){
        int num = this.sqlManager.updateTemplateById(bizContract);
        if (num == 0){
            return 0;
        }
        LambdaQuery<BizContractPayment> query = sqlManager.lambdaQuery(BizContractPayment.class);
        query.andEq(BizContractPayment::getBizId,bizContract.getId()).delete();
        if (0 < bizContract.getPaymentList().size()){
            for (BizContractPayment payment : bizContract.getPaymentList()){
                payment.setBizId(bizContract.getId());
                this.sqlManager.insert(payment);
            }
        }
        return num;
    }

    @Override
    public boolean addCheck(BizContract bizContract){
        LambdaQuery<BizContract> query = sqlManager.lambdaQuery(BizContract.class);
        List<BizContract> orgList = query.andEq(BizContract::getContractName,bizContract.getContractName())
                .orEq(BizContract::getContractNo,bizContract.getContractNo())
                .andEq(BizContract::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .select();
        return 0 >= orgList.size();
    }

    @Override
    public boolean updateCheck(BizContract bizContract){
        LambdaQuery<BizContract> query = sqlManager.lambdaQuery(BizContract.class);
        List<BizContract> orgList = query.andEq(BizContract::getIsDelete,IsDeleteEnum.NOTDELETE.getCode())
                .andNotEq(BizContract::getId,bizContract.getId()).and(query.condition()
                        .andEq(BizContract::getContractName,bizContract.getContractName())
                        .orEq(BizContract::getContractNo,bizContract.getContractNo())).select();
        return 0 >= orgList.size();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(Long id){
        BizContract bizContract = new BizContract();
        bizContract.setId(id);
        bizContract.setIsDelete(IsDeleteEnum.DELETE.getCode());
        return this.sqlManager.updateTemplateById(bizContract);
    }

    @Override
    public RtnInfo<BizContract> getInfo(Long id){
        BizContract bizContract = this.selectById(id);
        if (null == bizContract){
            return RtnInfo.error(RtnConstant.Code.PARAMS_REEOR,"未查到相关信息，请检查上送数据是否正确");
        } else {
            LambdaQuery<BizContractPayment> query = sqlManager.lambdaQuery(BizContractPayment.class);
            bizContract.setPaymentList(query.andEq(BizContractPayment::getBizId,id).select());
            return  RtnInfo.success(bizContract);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RtnInfo finishContract(Long id){
        BizContract bizContract = this.selectById(id);
        LambdaQuery<BizContractPayment> query = sqlManager.lambdaQuery(BizContractPayment.class);
        List<BizContractPayment> paymentList = query.andEq(BizContractPayment::getBizId,id).select();
        if (0 == paymentList.size()){
            return RtnInfo.error(RtnConstant.Code.PARAMS_REEOR,"没有维护支付节点，不可完成合同");
        }
        BigDecimal totalPayment = BigDecimal.ZERO;
        for (BizContractPayment payment:paymentList){
            totalPayment = totalPayment.add(payment.getPaymentAmount());
        }
        if (!(totalPayment.compareTo(bizContract.getContractAmount()) >= 0)){
            return RtnInfo.error(RtnConstant.Code.PARAMS_REEOR,"支付金额必须大于或等于合同金额，不可完成合同");
        }
        bizContract.setStatus(BizContractStatusEnum.FINISH.getCode());
        return RtnInfo.success(this.sqlManager.updateTemplateById(bizContract));
    }


}
